package ink.metoo.gude.module.security.util

import ink.metoo.gude.module.security.domain.JwtConst
import ink.metoo.gude.properties.JwtProperties
import ink.metoo.gude.module.security.domain.ddl.User
import io.jsonwebtoken.Claims
import io.jsonwebtoken.JwtBuilder
import io.jsonwebtoken.JwtParserBuilder
import io.jsonwebtoken.Jwts
import io.jsonwebtoken.security.Keys
import java.nio.charset.StandardCharsets
import java.util.*
import javax.crypto.SecretKey

class JwtTokenMapper(private val properties: JwtProperties) {

    private val secretKey: SecretKey = Keys.hmacShaKeyFor(properties.secret.toByteArray(StandardCharsets.UTF_8))

    val jwtBuilder: JwtBuilder
        get() = Jwts.builder()
            .signWith(secretKey)
            .issuedAt(Date())

    val jwtParserBuilder: JwtParserBuilder
        get() = Jwts.parser()
            .verifyWith(secretKey)

    fun createToken(user: User): String {
        return jwtBuilder
            .expiration(Date(System.currentTimeMillis() + properties.expirationTime.toMillis()))
            .id(user.id.toString())
            .subject(user.email)
            .claim(JwtConst.PASSWORD_VALID_VERIFICATION_NAME, user.passwordLastModifiedDate)
            .compact()
    }

    fun getClaims(token: String): Claims {
        return jwtParserBuilder
            .build()
            .parseSignedClaims(token)
            .getPayload()
    }

    fun isTokenExpired(claims: Claims): Boolean {
        val expiration = claims.expiration
        return expiration != null && expiration.before(Date())
    }
}